
#########################################################################

# Copyright (C) Flavio Piccinelli 2012 <flavio.picci@gmail.com>

#########################################################################

# MyThread.rb
# This file is part of "AriaAperta".

# AriaAperta is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# AriaAperta is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with AriaAperta.  If not, see <http://www.gnu.org/licenses/>.

#########################################################################
#########################################################################


#########################################################################
# Required libraries
#########################################################################
require "lib/Aria"
require "lib/Utils"
#########################################################################

include Aria
include Utils

module MyThread

	def thread_loop()
		
		loop do
			Aria::shut_all_err
			users = Utils::check_ack
			Aria::shut_vm(users, nil)
			sleep 600
		end
		
	end

	def thread_routine(sslSocket, semaphore)

		begin
			sslSocket.puts("username: \nEOL")
			username = sslSocket.gets_all
			
			sslSocket.puts("password: \nEOL")
			password = sslSocket.gets_all

			puts "authenticating user #{username}"

			authenticated = Utils::authenticate_user(username, password)
			if authenticated
				sslSocket.puts "User #{username} authenticated\nEOL"
			else
				sslSocket.puts "Login failed, wrong username or password\nRET"
			end
		end until authenticated

		req = sslSocket.gets_all

		credentials = "#{username}:#{password}"
		
		case req
		when "0"
			voip_req(sslSocket, credentials, semaphore)
		when "1"
			vm_req(sslSocket, credentials, semaphore)
		when "2"
			ack(sslSocket, credentials)
		when "3"
			close(sslSocket, credentials)
		else
			lineOut = "wrong reqest, retry\nEOF"
			sslSocket.puts lineOut
		end
		
	ensure
		puts "thread exit"
		sslSocket.close
	end

	def voip_req(sslSocket, credentials, semaphore)

		imgs = Aria::get_imgs(false)
		img_id = imgs[0][0].to_i

		hosts = Utils::select_hosts
		hosts_hash = hosts[0]
		hosts_stri = hosts[1]

# 		puts hosts_hash
# 		puts hosts_stri
		sslSocket.puts hosts_stri

		if hosts_hash != 0
			host_na = sslSocket.gets_all.chomp
			host_id = hosts_hash[host_na]
		else
			Thread.exit
		end

		vm_id = Aria::start_vm(host_id, [img_id, imgs[0][1], imgs[0][3]], credentials, semaphore)
		Utils::do_ack(credentials)

		if vm_id.is_a? Fixnum
			udp_port = 30000 + vm_id
			lineOut = "#{udp_port}+#{host_na}"
		else
			lineOut = vm_id
		end

		sslSocket.puts lineOut
		sslSocket.puts "EOF"

	end

	def vm_req(sslSocket, credentials, semaphore)

		imgs = Aria::get_imgs(true)
		imgs_arr = Array.new
		imgs_check = Array.new
		if imgs.length == 0
			lineOut = "Sorry no images available at this time, try later\nBye..."
			eof = "EOF"
		else
			lineOut = "Available images\n\nID	name		description\n"
			for img in imgs
				lineOut += "#{img[0]}	#{img[1]}	#{img[2]}\n"
				imgs_check << img[0]
				imgs_arr[img[0]] = [img[1], img[3]]
			end
			lineOut += "\nselect an image ID\nimage ID:"
			eof = "EOL"
		end

# 		puts lineOut

		sslSocket.puts lineOut
		sslSocket.puts eof
		
		if imgs.length == 0
			Thread.exit
		end

		while !imgs_check.include?(img_id = sslSocket.gets_all.chomp.to_i)
			lineOut = "Image ID error, select another one...\nImage ID:\nRET"
			sslSocket.puts lineOut
			puts img_id
		end

		hosts = Utils::select_hosts
		hosts_hash = hosts[0]
		hosts_stri = hosts[1]

		sslSocket.puts hosts_stri
		
		if hosts_hash != 0
			host_na = sslSocket.gets_all.chomp
			host_id = hosts_hash[host_na]
		else
			Thread.exit
		end

		vm_id = Aria::start_vm(host_id, [img_id, imgs_arr[img_id]].flatten, credentials, semaphore)
		Utils::do_ack(credentials)

		if vm_id.is_a? Fixnum
			vnc_port = 5900 + vm_id
			udp_port = 30000 + vm_id
			lineOut = "vm #{vm_id} started on host #{host_na}...\n"
			lineOut += "vnc port: #{vnc_port}, udp port: #{udp_port}"
			# 		puts lineOut
		else
			lineOut = vm_id
		end

		sslSocket.puts lineOut
		sslSocket.puts "EOF"

	end

	def ack(sslSocket, credentials)

		ack = Utils::do_ack(credentials)
		if ack
			sslSocket.puts "ack ok\nEOF"
		else
			sslSocket.puts "ack failed, try again\nEOF"
		end

	end

	def close(sslSocket, credentials)
		cred_arr = Array.new
		vm_ids = Array.new
		lineIn = sslSocket.gets_all.chomp
		
		if lineIn == "all"
			credentials = credentials.split(":")[0]
			vm_ids = nil
		else
			vm_ids = Utils::parse_req(lineIn, ",", "..")
		end
		puts vm_ids
		cred_arr << credentials
		vms_shut = Aria::shut_vm(cred_arr, vm_ids)
		sslSocket.puts "#{vms_shut} vm/s stopped\nEOL"
	end

end
